#pragma once
#include <iostream>
#include <pthread.h>
#include <cstring>
#include <string>

class thread
{
public:
    typedef void (*func_t)(void*); // 函数名就是指针变量
    enum Status
    {
        NEW,
        RUNNING,
        EXITED
    };

public:
    thread(int num, func_t func, void* args)
        : _id(0)
        , _func(func)
        , _args(args)
        , _status(NEW)
    {
        char buff[64];
        snprintf(buff, 64, "thread-%d", num);
        _name = buff;
    }

    std::string threadname()
    {
        return _name;
    }

    int status()
    {
        return _status;
    }

    pthread_t pthread_id()
    {
        if(_status == RUNNING)
            return _id;
        else
            return 0;
    }

    static void* runHelper(void* args) // 为了保证可以作为参数传入pthread_create，要加static去掉this指针参数
    {
        thread* th = static_cast<thread*>(args); // 为了调用，传入的函数方法，所以要传入this

        (*th)(); // 防止静态成员无法调用类内对象，所以使用仿函数调用
        return nullptr;
    }

    void operator()() // 仿函数调用
    {
        if(_func != nullptr)
            _func(_args);
    }

    void run()
    {
        int n = pthread_create(&_id, nullptr, runHelper, (void*)this);
        if(n != 0)
        {
            std::cerr << "errno : " << n << strerror(n) << std::endl;
        }
        _status = RUNNING;
    }

    void join()
    {
        pthread_join(_id, nullptr);
        _status = EXITED;
    }

    ~thread()
    {}
private:
    pthread_t _id;
    std::string _name;
    void* _args;
    func_t _func;
    Status _status;
};